package busterminalweb.action.trip;

import busterminal.entity.Bus;
import busterminal.entity.BusImplementation;
import busterminal.entity.Route;
import busterminal.entity.RouteImplementation;
import busterminal.entity.Trip;
import busterminal.entity.TripImplementation;
import busterminal.entity.service.TripState;
import busterminal.exception.BusinessException;
import busterminal.exception.DatabaseException;
import busterminal.persistence.TripDAO;
import busterminal.services.ServiceLocator;
import busterminalweb.action.Action;
import busterminalweb.action.ActionResult;
import java.text.ParseException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Сохранить рейс
 */
public class SaveTripAction implements Action {

    /**
     * Регулярное выражение для проверки корректности ввода даты в формате
     * <code>DD.MM.YYYY</code>
     */
    private static final String CORRECT_DATE_FORMAT = "^((0[1-9]|[12]\\d|3[01])\\.(0[13578]|1[02])\\.((19|[2-9]\\d)\\d{2}))|((0[1-9]|[12]\\d|30)\\.(0[13456789]|1[012])\\.((19|[2-9]\\d)\\d{2}))|((0[1-9]|1\\d|2[0-8])\\.02\\.((19|[2-9]\\d)\\d{2}))|(29\\.02\\.((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))$";
    /**
     * Регулярное выражение для проверки корректности ввода идентификатора
     */
    private static final String CORRECT_ID_FORMAT = "^[0-9]*$";
    /**
     * Регулярное выражение для проверки корректности ввода числа
     */
    private static final String CORRECT_NUMBER_FORMAT = "^[1-9]([0-9]*)$";

    /**
     * Выполнить действие
     * @param request запрос
     * @param response ответ
     * @return страница, которой нужно передать управление
     */
    @Override
    public ActionResult execute(HttpServletRequest request, HttpServletResponse response) {
        if (request.getParameter("saveButton") != null) {
            if (!request.getParameter("id").trim().matches(CORRECT_ID_FORMAT)) {
                throw new BusinessException("Incorrect trip id=" + request.getParameter("id").trim());
            }
            int id = Integer.parseInt(request.getParameter("id").trim());
            Trip trip = (id == 0) ? new TripImplementation() : ServiceLocator.getService(TripDAO.class).read(id);

            if (request.getParameter("route") != null && request.getParameter("route").trim().matches(CORRECT_NUMBER_FORMAT)) {
                int routeId = Integer.parseInt(request.getParameter("route").trim());
                Route route = new RouteImplementation();
                route.setId(routeId);
                trip.setRoute(route);
            } else {
                throw new BusinessException("You should define route");
            }

            if (request.getParameter("tripState") != null && !request.getParameter("tripState").trim().isEmpty()) {
                trip.setTripState(TripState.valueOf(request.getParameter("tripState").trim().toUpperCase()));
            } else {
                throw new BusinessException("You should define trip state");
            }

            if (request.getParameter("tripDate") != null && request.getParameter("tripDate").trim().matches(CORRECT_DATE_FORMAT)) {
                try {
                    trip.setTripDate(request.getParameter("tripDate").trim());
                } catch (ParseException parseException) {
                    throw new DatabaseException("Cannot parse trip date=" + request.getParameter("tripDate").trim(), parseException);
                }
            } else {
                throw new BusinessException("You should define trip date in DD.MM.YYYY format");
            }

            if (request.getParameter("bus") != null && request.getParameter("bus").trim().matches(CORRECT_NUMBER_FORMAT)) {
                int busId = Integer.parseInt(request.getParameter("bus").trim());
                Bus bus = new BusImplementation();
                bus.setId(busId);
                trip.setBus(bus);
            } else {
                throw new BusinessException("You should define bus");
            }

            if (request.getParameter("driverName") != null && !request.getParameter("driverName").isEmpty()) {
                trip.setDriverName(request.getParameter("driverName"));
            } else {
                throw new BusinessException("You should define driver name");
            }

            if (request.getParameter("conductorName") != null && !request.getParameter("conductorName").isEmpty()) {
                trip.setConductorName(request.getParameter("conductorName"));
            } else {
                throw new BusinessException("You should define conductor name");
            }

            TripDAO tripDAO = ServiceLocator.getService(TripDAO.class);
            if (id != 0) {
                tripDAO.update(trip);
            } else {
                tripDAO.create(trip);
            }
        }

        //список, который нужно загрузить при возврате на главную страницу
        request.getSession().setAttribute("showPage", "trip-list");

        //main - это action, который никак сервлетом не обрабатывается,
        //т.е. открывается главная страница
        return ActionResult.redirect("main");
    }

    /**
     * Получить имя действия
     * @return имя действия
     */
    @Override
    public String getName() {
        return "trip.save";
    }
}
